package com.qzsoft.zhjd.server.common.utils;

import java.math.BigDecimal;
import java.math.RoundingMode;

import org.apache.commons.lang3.StringUtils;

/**
 * @ClassName NumberUtils
 * @Description 数字工具类
 * @author linhuawei
 * @since 2021-08-27
 */
public class NumberUtils {

    /**
     * @Title inRange
     * @Description 是否在指定数据范围
     * @param value 要判断的数据
     * @param max   最大值
     * @param min   最小值
     * @return true|false
     */
    public static boolean inRange(BigDecimal value, BigDecimal max, BigDecimal min) {
        return 1 > value.compareTo(max) && -1 < value.compareTo(min);
    }

    /**
     * @Title notInRange
     * @Description 是否部在指定数据范围
     * @param value 要判断的数据
     * @param max   最大值
     * @param min   最小值
     * @return true|false
     */
    public static boolean notInRange(BigDecimal value, BigDecimal max, BigDecimal min) {
        return !inRange(value, max, min);
    }

    /**
     * @Title inErrorRange
     * @Description 判断是否在偏差范围内
     * @param value     要判断的数据
     * @param baseValue 基准值
     * @param error     偏差数据
     * @return true|false
     */
    public static boolean inErrorRange(BigDecimal value, BigDecimal baseValue, BigDecimal error) {
        BigDecimal max = baseValue.add(error);
        BigDecimal min = baseValue.subtract(error);
        return inRange(value, max, min);
    }

    /**
     * @Title notInErrorRange
     * @Description 判断是否不在偏差范围内
     * @param value     要判断的数据
     * @param baseValue 基准值
     * @param error     偏差数据
     * @return true|false
     */
    public static boolean notInErrorRange(BigDecimal value, BigDecimal baseValue, BigDecimal error) {
        return !inErrorRange(value, baseValue, error);
    }

    /**
     * @Title setScale
     * @Description 保留小数位（四舍五入）
     * @param val   原值
     * @param scale 小数位
     * @return 数值
     */
    public static BigDecimal setScale(BigDecimal val, int scale) {
        return null == val ? null : val.setScale(scale, RoundingMode.HALF_UP);
    }

    /**
     * @Title strToBigDecimal
     * @Description 字符串转BigDecimal数字
     * @param str   需要处理的字符串
     * @param scale 保留几位小时（四舍五入）
     * @return 转化后的BigDecimal数字
     */
    public static BigDecimal strToBigDecimal(String str, int scale) {
        BigDecimal val = strToBigDecimal(str, BigDecimal.ZERO);
        return null == val ? null : val.setScale(scale, RoundingMode.HALF_UP);
    }

    /**
     * @Title strToBigDecimal
     * @Description 字符串转BigDecimal数字
     * @param str 需要处理的字符串
     * @return 转化后的BigDecimal数字
     */
    public static BigDecimal strToBigDecimal(String str) {
        return strToBigDecimal(str, BigDecimal.ZERO);
    }

    /**
     * @Title strToBigDecimal
     * @Description 字符串转BigDecimal数字
     * @param str          需要处理的字符串
     * @param defaultValue 默认值
     * @return 转化后的BigDecimal数字
     */
    public static BigDecimal strToBigDecimal(String str, BigDecimal defaultValue) {
        if (StringUtils.isBlank(str)) {
            return defaultValue;
        }
        try {
            return new BigDecimal(str);
        } catch (Exception e) {
            return defaultValue;
        }
    }

    /**
     * @Title isZero
     * @Description 判断数据是否为0
     * @param value 需要判断的数据
     * @return true|false
     */
    public static boolean isZero(BigDecimal value) {
        return 0 == BigDecimal.ZERO.compareTo(value);
    }

    /**
     * @Title isZero
     * @Description 判断数据是否为0
     * @param value 需要判断的数据
     * @return true|false
     */
    public static boolean isZero(Long value) {
        return 0 == value;
    }

    /**
     * @Title isZero
     * @Description 判断数据是否不为0
     * @param value 需要判断的数据
     * @return true|false
     */
    public static boolean notZero(BigDecimal value) {
        return 0 != BigDecimal.ZERO.compareTo(value);
    }

    /**
     * @Title isZero
     * @Description 判断数据是否不为0
     * @param value 需要判断的数据
     * @return true|false
     */
    public static boolean notZero(Long value) {
        return 0 != value;
    }

    /**
     * @Title strToInteger
     * @Description 字符串转int数字
     * @param str 需要处理的字符串
     * @return 转化后的int数字
     */
    public static Integer strToInteger(String str) {
        return strToInteger(str, 0);
    }

    /**
     * @Title strToInteger
     * @Description 字符串转int数字
     * @param str          需要处理的字符串
     * @param defaultValue 默认值
     * @return 转化后的int数字
     */
    public static Integer strToInteger(String str, Integer defaultValue) {
        if (StringUtils.isBlank(str)) {
            return defaultValue;
        }
        try {
            return Integer.parseInt(str);
        } catch (Exception e) {
            return defaultValue;
        }
    }

    /**
     * @Title: roundHalfUp
     * @Description: 字符串数字四舍五入
     * @param str   需要处理的字符串
     * @param digit 需要保留小数位数
     * @return String 处理后的字符串数字
     */
    public static String roundHalfUp(String str, int digit) {
        if (null != str) {
            try {
                double temp = Double.parseDouble(str);
                temp = new BigDecimal(temp).setScale(digit, BigDecimal.ROUND_HALF_UP).doubleValue();
                str = String.valueOf(temp);
            } catch (Exception e) {

            }
        }
        return str;
    }

    /**
     * @Title: roundHalfUp
     * @Description: 数字四舍五入
     * @param num   要处理的数字
     * @param digit 小数保留位数
     * @return BigDecimal 处理后的数字
     */
    public static BigDecimal roundHalfUp(BigDecimal num, int digit) {
        if (null != num) {
            num = num.setScale(digit, BigDecimal.ROUND_HALF_UP);
        }
        return num;
    }

    /**
     * @Title sum
     * @Description 计算数组总和
     * @param values 数组
     * @return 数组总和
     */
    public static BigDecimal sum(BigDecimal... values) {
        BigDecimal sum = BigDecimal.ZERO;
        if (null != values && 0 < values.length) {
            for (BigDecimal value : values) {
                if (null != value) {
                    sum = sum.add(value);
                }
            }
        }
        return sum;
    }

    /**
     * @Title countRatio
     * @Description 计算占比，四舍五入保留指定位数小数
     * @param total 总数
     * @param value 需要计算的数值
     * @param digit 小数位数
     * @return 百分比
     */
    public static BigDecimal countRatio(BigDecimal total, BigDecimal value, int digit) {
        if (null == value || null == total || 0 == BigDecimal.ZERO.compareTo(total)) {
            return null;
        }
        return value.multiply(new BigDecimal(100)).divide(total, digit, RoundingMode.HALF_UP);
    }

    /**
     * @Title countValue
     * @Description 计算数值，四舍五入保留指定位数小数
     * @param total 总数
     * @param ratio 百分比
     * @param digit 小数位数
     * @return 数值
     */
    public static BigDecimal countValue(BigDecimal total, BigDecimal ratio, int digit) {
        if (null == ratio || null == total || 0 == BigDecimal.ZERO.compareTo(total)) {
            return null;
        }

        return ratio.multiply(total).divide(new BigDecimal(100), digit, RoundingMode.HALF_UP);
    }

}
